package org.ch02.hw.demo07;

import java.lang.reflect.Field;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author ZJL
 * @date 2025-03-18
 */
public class SqlGenerate {
    /**
     * 基于 Bean对象，生成查询所有字段的语句
     *
     * @param beanClass 实体对象（Bean）的 Class 对象
     * @return 查询所有字段的 SQL 语句
     */
    public static String generateSelect(Class<?> beanClass) {
        // 功能实现...
        Field[] declaredFields = beanClass.getDeclaredFields();
        StringBuffer sql = new StringBuffer("select ");
        // 获取实体对象的所有字段
        for (Field field : declaredFields) {
            sql.append(convertToSnake(field.getName())).append(",");
        }
        // 删除拼接最后一个字段后面的逗号
        sql.deleteCharAt(sql.length() - 1);
        sql.append(" from ").append(convertToSnake(beanClass.getSimpleName()));
        return sql.toString();
    }

    /**
     * 实现把驼峰命名的字符串转换为数据库的命名规范，如：
     * xxxXxxXxx - xxx_xxx_xxx
     * XxxXxxXxx - xxx_xxx_xxx
     * @param input
     * @return
     */
    public static String convertToSnake(String input) {
        return input.replaceAll("([A-Z])", "_$1").toLowerCase().replaceAll("^_", "");
    }

    /**
     * 基于 Bean对象，生成查询所有字段的语句，并且根据条件查询
     * @param beanClass 实体对象（Bean）的 Class 对象
     * @param cond 查询条件
     * @return 查询的 SQL 语句
     */
    public static String generateSelect(Class<?> beanClass ,Map<String,Object> cond) {
        StringBuilder sql = new StringBuilder(generateSelect(beanClass));
        if (cond == null && cond.isEmpty()) {
            return sql.toString();
        }
        // where id = ? and name = ?
        sql.append(" where ");
        for (Map.Entry<String,Object> entry : cond.entrySet()) {
            sql.append(entry.getKey()).append("=?").append(" and ");
        }
        return sql.substring(0, sql.length() - 5);
    }

    /**
     * 正则表达式 把数据库中字段 为 xxx_xxx_xxx 转换为 驼峰命名 xxxXxxXxx
     * @param input 需要转换的字段
     * @return 转换后的字段
     */
    public static String convertToCamelCase(String input) {
        // 定义正则表达式匹配下划线及其后面的字符
        Pattern pattern = Pattern.compile("_(.)");
        Matcher matcher = pattern.matcher(input);

        // 使用StringBuffer来构建结果字符串
        StringBuffer result = new StringBuffer();

        // 遍历所有匹配项
        while (matcher.find()) {
            // 将匹配项中的字符转换为大写
            matcher.appendReplacement(result, matcher.group(1).toUpperCase());
        }
        // 将剩余部分添加到结果中
        matcher.appendTail(result);

        return result.toString();
    }

    /**
     * 根据 Bean 对象生成对应的添加数据的 SQL
     *
     * @param beanClass - 与数据表对应
     * @return insert SQL
     */
    public static String generateInsert(Class<?> beanClass) {
        // insert into 表名(字段名称,...) values(?,?,?)
        StringBuilder sql = new StringBuilder("insert into ");
        sql.append(convertToSnake(beanClass.getSimpleName())).append("(");
        Field[] fields = beanClass.getDeclaredFields();
        //循环遍历 Bean 对象中的字段 - Bean 对象的字段和数据表的字段一一对应
        for (Field field : fields) {
            sql.append(convertToSnake(field.getName())).append(",");
        }
        sql.deleteCharAt(sql.length() - 1);
        sql.append(") values(");
        // 再次循环（只需要循环次数），添加 ? 为占位符
        for (int i = 0; i < fields.length; i++) {
            sql.append("?").append(",");
        }
        sql.deleteCharAt(sql.length() - 1);
        sql.append(")");
        return sql.toString();
    }
}
